#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<string.h>

#define LEFT "["
#define RIGHT "]"
#define SIZE 1024
#define pwdsize 200
char command[SIZE];
char* arg[30];
int argc=0;
int status;
int quit = 0;
int isbuilt;
char pwdbuff[pwdsize];
int exit_code,exit_signal;

char* getuser(){
  return getenv("USER");
}

char* gethostname(){
  return getenv("HOSTNAME");
}

char* getpwd(){
  getcwd(pwdbuff,pwdsize);
  return pwdbuff;
 // return getenv("PWD");
}

void interact(){
  printf(LEFT "%s@%s %s" RIGHT " ##",getuser(),gethostname(),getpwd()); 
  fgets(command,SIZE,stdin);
  command[strlen(command)-1] = '\0';
}

void parse(){
  argc = 0;
  if(strlen(command)==0) return;
  arg[argc++] = strtok(command," ");
  while((arg[argc++]=strtok(NULL," ")) != NULL);
}

void ordcommand(){
   pid_t id = fork();
   if(id<0){
      perror("fork");
      exit(1);
   }else if(id==0){
      execvp(arg[0],arg); 
      exit(44);
   }else{
      status = 0;
      pid_t rpid = wait(&status);
      if(rpid<=0){
          perror("wait");
          return;
      }
      exit_code =  (status>>8)&0XFF;
      exit_signal = status&0X7F;
      if(exit_code == 44){
          printf("no found command\n");
      }else{
          printf("runnig command successful\n");
      }
  }
}

int builtcommand(){
    if(strcmp(arg[0],"quit")==0){
        return quit=1;
    }else if(strcmp(arg[0],"cd")==0){
        if(argc<1 || strcmp(arg[1],".")==0) return 1;
        else if(strcmp(arg[1],"..")==0){
            getcwd(pwdbuff,pwdsize);
            int j=strlen(pwdbuff)-1;
            while(pwdbuff[j]!='/') --j;
            pwdbuff[j+1]='\0';
        }else if(strcmp(arg[1],"~")==0){
            strcpy(pwdbuff,getenv("PWD"));
        }else{
            strcpy(pwdbuff,arg[1]);
        }
        int ret = chdir(pwdbuff);
        if(ret != 0){
          perror("no found dir\n");
        }
        return 1;
    }
    return 0;
}

int main(){
  while(!quit){
    //交互
    interact();
    //命令解析
    parse();
    if(argc == 0) continue;
    //判断内建命令
    isbuilt = builtcommand();
    //普通命令,创建子进程执行
    if(isbuilt==0) ordcommand();
  }
  return 0;
}
